<template>
  <div class="flow-editor">
    <div class="toolbar">
      <el-button-group>
        <el-button @click="addNode('rect')">矩形节点</el-button>
        <el-button @click="addNode('circle')">圆形节点</el-button>
        <el-button @click="mode = 'line'">连线</el-button>
        <el-button @click="mode = 'select'">选择</el-button>
        <el-button @click="clearCanvas">清空</el-button>
      </el-button-group>
    </div>
    <canvas
        ref="canvas"
        @mousedown="handleMouseDown"
        @mousemove="handleMouseMove"
        @mouseup="handleMouseUp"
        class="flow-canvas"
    ></canvas>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue'

// 画布相关
const canvas = ref(null)
const ctx = ref(null)
const mode = ref('select') // select, line
const nodes = ref([])
const lines = ref([])
const isDragging = ref(false)
const selectedNode = ref(null)
const startNode = ref(null)

// 初始化画布
onMounted(async () => {
  await nextTick()
  const canvasEl = canvas.value
  ctx.value = canvasEl.getContext('2d')

  // 设置画布大小
  canvasEl.width = canvasEl.offsetWidth
  canvasEl.height = canvasEl.offsetHeight

  // 初始绘制
  draw()
})

// 绘制所有内容
const draw = () => {
  const context = ctx.value
  if (!context) return

  // 清空画布
  context.clearRect(0, 0, canvas.value.width, canvas.value.height)

  // 绘制所有节点
  nodes.value.forEach(node => {
    context.beginPath()
    if (node.type === 'rect') {
      context.rect(node.x, node.y, node.width, node.height)
    } else if (node.type === 'circle') {
      context.arc(node.x + node.width/2, node.y + node.height/2, node.width/2, 0, Math.PI * 2)
    }
    context.fillStyle = node === selectedNode.value ? '#e6f7ff' : '#fff'
    context.fill()
    context.strokeStyle = '#1890ff'
    context.stroke()

    // 绘制文本
    context.fillStyle = '#000'
    context.textAlign = 'center'
    context.textBaseline = 'middle'
    context.fillText(node.text, node.x + node.width/2, node.y + node.height/2)
  })

  // 绘制所有连线
  lines.value.forEach(line => {
    context.beginPath()
    context.moveTo(line.start.x + line.start.width/2, line.start.y + line.start.height/2)
    context.lineTo(line.end.x + line.end.width/2, line.end.y + line.end.height/2)
    context.strokeStyle = '#1890ff'
    context.stroke()
  })
}

// 添加节点
const addNode = (type) => {
  const node = {
    id: Date.now(),
    type,
    x: 100,
    y: 100,
    width: 100,
    height: 50,
    text: `节点${nodes.value.length + 1}`
  }
  nodes.value.push(node)
  draw()
}

// 鼠标事件处理
const handleMouseDown = (e) => {
  const rect = canvas.value.getBoundingClientRect()
  const x = e.clientX - rect.left
  const y = e.clientY - rect.top

  // 查找点击的节点
  const node = nodes.value.find(n =>
      x >= n.x && x <= n.x + n.width &&
      y >= n.y && y <= n.y + n.height
  )

  if (node) {
    if (mode.value === 'select') {
      selectedNode.value = node
      isDragging.value = true
    } else if (mode.value === 'line') {
      startNode.value = node
    }
  } else {
    selectedNode.value = null
  }

  draw()
}

const handleMouseMove = (e) => {
  if (!isDragging.value || !selectedNode.value) return

  const rect = canvas.value.getBoundingClientRect()
  const x = e.clientX - rect.left
  const y = e.clientY - rect.top

  selectedNode.value.x = x - selectedNode.value.width / 2
  selectedNode.value.y = y - selectedNode.value.height / 2

  draw()
}

const handleMouseUp = (e) => {
  if (mode.value === 'line' && startNode.value) {
    const rect = canvas.value.getBoundingClientRect()
    const x = e.clientX - rect.left
    const y = e.clientY - rect.top

    // 查找目标节点
    const endNode = nodes.value.find(n =>
        x >= n.x && x <= n.x + n.width &&
        y >= n.y && y <= n.y + n.height
    )

    if (endNode && endNode !== startNode.value) {
      lines.value.push({
        id: Date.now(),
        start: startNode.value,
        end: endNode
      })
    }

    startNode.value = null
    draw()
  }

  isDragging.value = false
}

// 清空画布
const clearCanvas = () => {
  nodes.value = []
  lines.value = []
  draw()
}
</script>

<style scoped>
.flow-editor {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #f0f2f5;
  padding: 16px;
}

.toolbar {
  margin-bottom: 16px;
}

.flow-canvas {
  flex: 1;
  background: #fff;
  border: 1px solid #d9d9d9;
  border-radius: 2px;
}
</style>
